<?php


namespace App\HttpController;


//use App\Annotation\AnnotationParser;
use App\Service\AuthService;
use App\Utility\JwtManager;
use EasySwoole\EasySwoole\ServerManager;
use EasySwoole\Http\Message\Status;
use EasySwoole\HttpAnnotation\AnnotationController;
use EasySwoole\HttpAnnotation\AnnotationTag\ApiAuth;
use EasySwoole\Mysqli\Exception\Exception;
use Throwable;
use function Swoole\Coroutine\Http\post;

/**
 * 基础http控制器类
 * Class BaseController
 * @package App\HttpController
 */
abstract class BaseController extends AnnotationController
{
    protected $userId;
    protected $username;
    protected $userInfo;
    protected $ip;
    protected $uid;

    /**
     * @param string|null $action
     * @return bool|null
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\ORM\Exception\Exception
     */
    protected function onRequest(?string $action): ?bool
    {
        $content = $this->request()->getBody()->__toString();
        $raw_array = json_decode($content, true);
        // 真实IP地址
        $this->ip = ServerManager::getInstance()->getSwooleServer()->connection_info($this->request()->getSwooleRequest()->fd)['remote_ip'];

        // 获取不需要验证的类方法
        $whiteList = []; // token验证白名单 , 值为类方法地址
        $whiteList = [
            'App\HttpController\Index\index',//测试接口
            'App\HttpController\Index\doc',//api文档
            'App\HttpController\Index\lvy',//api文档
            'App\HttpController\Login\weLogin',//微信登录
            'App\HttpController\Login\codeLogin',//验证码登录
            'App\HttpController\Login\passLogin',//密码登录
            'App\HttpController\Sms\send',
            'App\HttpController\Callback\mxwepay',
            'App\HttpController\Configure\getRepairType',
            'App\HttpController\Configure\getRepairDetail',
            'App\HttpController\Configure\getFreeService',
            'App\HttpController\Configure\getHomeNav',
            'App\HttpController\Configure\getAdjacentNav',
            'App\HttpController\Configure\getBanner',
            'App\HttpController\Configure\getOneKey',
            'App\HttpController\Configure\newsConfig',
            'App\HttpController\Configure\getNewsType',
            'App\HttpController\Configure\getTitle',
            'App\HttpController\Configure\getShareService',
            'App\HttpController\Configure\getArticle',
            'App\HttpController\Configure\getShopNavS',
            'App\HttpController\Configure\getShopNavH',
            'App\HttpController\Configure\getSplash',
            'App\HttpController\Notice\getNotice',
            'App\HttpController\Notice\getNoticeList',
            'App\HttpController\Notice\getNoticeDetail',
            'App\HttpController\Share\getTopic',
            'App\HttpController\Share\getServiceItems',
            'App\HttpController\Active\getList',
            'App\HttpController\Community\getTopic',
            'App\HttpController\Community\getNews',
            'App\HttpController\Shop\getShopCate',
            'App\HttpController\Shop\getShopCateS',
            'App\HttpController\Shop\getGoodsList',
            'App\HttpController\Shop\getGoodDetail',
            'App\HttpController\Shop\getHomeShopNav',
            'App\HttpController\Questionnaire\getQuestionStatus',
            'App\HttpController\Questionnaire\getQuestion',
            'App\HttpController\Questionnaire\setQuestion',
            'App\HttpController\Vote\getVoteStatus',
            'App\HttpController\Vote\getVoteItem',
            'App\HttpController\Vote\rank',
        ];

        $whiteBind = [
            'App\HttpController\Auth\bindPhone'
        ];

        // 如果访问的类方法不存在于白名单内，验证jwt，默认全部验证
        if (!in_array(static::class . '\\' . $action, $whiteList)) {
            $type = 0;
            if (!in_array(static::class . '\\' . $action, $whiteBind)) $type = 1;
            return $this->verifyJWT($type);
        }

        return true;
    }

    /**
     * 成功返回
     * @param null $result
     * @param string $msg
     * @return bool
     */
    protected function writeJsonSuccess($result = null, string $msg = 'success'): bool
    {
        return $this->writeJson(Status::CODE_OK, $result, $msg);
    }

    /**
     * 错误返回
     * @param string $msg
     * @return bool
     */
    protected function writeJsonError(string $msg = 'error'): bool
    {
        return $this->writeJson(Status::CODE_BAD_REQUEST, null, $msg);
    }

    /**
     * 返回json数据
     * @param int $statusCode
     * @param null $result
     * @param null $msg
     * @return bool
     */
    protected function writeJson($statusCode = 200, $result = null, $msg = null): bool
    {
        return ExceptionHandler::writeJson($this->response(), $statusCode, $result, $msg);
    }

    /**
     * JWT验证
     * @param int $type
     * @return bool
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\ORM\Exception\Exception
     */
    protected function verifyJWT(int $type = 0): bool
    {
        $token = $this->request()->getHeader('authorization');

        if (empty($token)) {
            $this->writeJson(403, null, '未登录');
            return false;
        }

        $userInfo = JwtManager::getInstance()->decode($token[0]);
        if ($userInfo['code'] !== 200) {
            $this->writeJson(403, null, $userInfo['msg']);
            return false;
        }

        $result = $userInfo['result'];
        $this->userInfo = $result['data'];
        $this->uid = $result['uid'];
        $this->userId = $result['userId'];
        $this->username = $result['username'];
        if ($type == 1){
            $res = AuthService::getInstance()->checkAuth($this->uid);
            if (!$res) {
                $this->writeJson(402, null, '未验证手机号');
                return false;
            }
        }
        return true;
    }
}